/*
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
*/
#include "format_field.h"
#include "vpc_format_def.h"

/******************* yuv sp*******************/
static int32_t yuv420sp_format_info_init(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t format)
{
    switch (format) {
        case VPC_PIPE_PIXEL_FORMAT_YUV_SEMIPLANAR_420:
            SET_VPC_PIC_FMT(YUV420_SEMI_PLANNAR, NV12);
            break;
        case VPC_PIPE_PIXEL_FORMAT_YVU_SEMIPLANAR_420:
            SET_VPC_PIC_FMT(YUV420_SEMI_PLANNAR, NV21);
            break;
        default: return 1;
    }

    SET_PIXEL_FMT(D8, D16, IDEL);
    SET_PIXEL_STEP(NUM_2, NUM_2); // xstep/ystep
    SET_DOWN_SAMPLE_COEFF(NUM_0, NUM_0, NUM_128, NUM_128, NUM_0, NUM_0); // 下采样系数
    SET_UVUP_EN(NUM_1); // 滤波开关
    SET_PORT_DU(NUM_30, NUM_14, NUM_0); // DU配置
    SET_PLANN_FMT(YUV_PLANNAR);

    return 0;
}

static int32_t yuv422sp_format_info_init(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t format)
{
    switch (format) {
        case VPC_PIPE_PIXEL_FORMAT_YUV_SEMIPLANAR_422:
            SET_VPC_PIC_FMT(YUV422_SEMI_PLANNAR, NV12);
            break;
        case VPC_PIPE_PIXEL_FORMAT_YVU_SEMIPLANAR_422:
            SET_VPC_PIC_FMT(YUV422_SEMI_PLANNAR, NV21);
            break;
        default: return 1;
    }

    SET_PIXEL_FMT(D8, D16, IDEL);
    SET_PIXEL_STEP(NUM_2, NUM_1); // xstep/ystep
    SET_DOWN_SAMPLE_COEFF(NUM_0, NUM_0, NUM_128, NUM_128, NUM_0, NUM_0); // 下采样系数
    SET_UVUP_EN(NUM_1); // 滤波开关
    SET_PORT_DU(NUM_30, NUM_14, NUM_0); // DU配置
    SET_PLANN_FMT(YUV_PLANNAR);
    return 0;
}

static int32_t yuv444sp_format_info_init(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t format)
{
    switch (format) {
        case VPC_PIPE_PIXEL_FORMAT_YUV_SEMIPLANAR_444:
            SET_VPC_PIC_FMT(YUV444_SEMI_PLANNAR, NV12);
            break;
        case VPC_PIPE_PIXEL_FORMAT_YVU_SEMIPLANAR_444:
            SET_VPC_PIC_FMT(YUV444_SEMI_PLANNAR, NV21);
            break;
        default: return 1;
    }

    SET_PIXEL_FMT(D8, D16, IDEL);
    SET_PIXEL_STEP(NUM_1, NUM_1); // xstep/ystep
    SET_DOWN_SAMPLE_COEFF(NUM_13, NUM_65, NUM_100, NUM_65, NUM_13, NUM_0); // 下采样系数
    SET_UVUP_EN(NUM_1); // 滤波开关
    SET_PORT_DU(NUM_7, NUM_15, NUM_15); // DU配置
    SET_PLANN_FMT(YUV_PLANNAR);
    return 0;
}

static int32_t yuv440sp_format_info_init(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t format)
{
    switch (format) {
        case VPC_PIPE_PIXEL_FORMAT_YUV_SEMIPLANAR_440:
            SET_VPC_PIC_FMT(YUV440_SEMI_PLANNAR, NV12);
            break;
        case VPC_PIPE_PIXEL_FORMAT_YVU_SEMIPLANAR_440:
            SET_VPC_PIC_FMT(YUV440_SEMI_PLANNAR, NV21);
            break;
        default: return 1;
    }

    SET_PIXEL_FMT(D8, D16, IDEL);
    SET_PIXEL_STEP(NUM_1, NUM_2); // xstep/ystep
    SET_DOWN_SAMPLE_COEFF(NUM_0, NUM_0, NUM_128, NUM_128, NUM_0, NUM_0); // 下采样系数
    SET_UVUP_EN(NUM_1); // 滤波开关
    SET_PORT_DU(NUM_22, NUM_11, NUM_11); // DU配置
    SET_PLANN_FMT(YUV_PLANNAR);
    return 0;
}

static int32_t yuv411sp_format_info_init(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t format)
{
    switch (format) {
        case VPC_PIPE_PIXEL_FORMAT_YUV_SEMIPLANAR_411:
            SET_VPC_PIC_FMT(YUV411_SEMI_PLANNAR, NV12);
            break;
        case VPC_PIPE_PIXEL_FORMAT_YVU_SEMIPLANAR_411:
            SET_VPC_PIC_FMT(YUV411_SEMI_PLANNAR, NV21);
            break;
        default: return 1;
    }

    SET_PIXEL_FMT(D8, D16, IDEL);
    SET_PIXEL_STEP(NUM_4, NUM_1); // xstep/ystep
    SET_DOWN_SAMPLE_COEFF(NUM_0, NUM_0, NUM_128, NUM_128, NUM_0, NUM_0); // 下采样系数
    SET_UVUP_EN(NUM_0); // 滤波开关
    SET_PORT_DU(NUM_22, NUM_11, NUM_11); // DU配置
    SET_PLANN_FMT(YUV_PLANNAR);
    return 0;
}

/******************* yuv plan*******************/
static int32_t yuv420p_format_info_init(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t format)
{
    switch (format) {
        case VPC_PIPE_PIXEL_FORMAT_YUV_PLANAR_420:
            SET_VPC_PIC_FMT(YUV420_PLANNAR, NV21);
            break;
        case VPC_PIPE_PIXEL_FORMAT_YVU_PLANAR_420:
            SET_VPC_PIC_FMT(YUV420_PLANNAR, NV12);
            break;
        default: return 1;
    }

    SET_PIXEL_FMT(D8, D8, D8);
    SET_PIXEL_STEP(NUM_2, NUM_2); // xstep/ystep
    SET_DOWN_SAMPLE_COEFF(NUM_0, NUM_0, NUM_128, NUM_128, NUM_0, NUM_0); // 下采样系数
    SET_UVUP_EN(NUM_1); // 滤波开关
    SET_PORT_DU(NUM_22, NUM_11, NUM_11); // DU配置
    SET_PLANN_FMT(YUV_PLANNAR);
    return 0;
}

static int32_t yuv422p_format_info_init(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t format)
{
    switch (format) {
        case VPC_PIPE_PIXEL_FORMAT_YUV_PLANAR_422:
            SET_VPC_PIC_FMT(YUV422_PLANNAR, NV21);
            break;
        case VPC_PIPE_PIXEL_FORMAT_YVU_PLANAR_422:
            SET_VPC_PIC_FMT(YUV422_PLANNAR, NV12);
            break;
        default: return 1;
    }

    SET_PIXEL_FMT(D8, D8, D8);
    SET_PIXEL_STEP(NUM_2, NUM_1); // xstep/ystep
    SET_DOWN_SAMPLE_COEFF(NUM_0, NUM_0, NUM_128, NUM_128, NUM_0, NUM_0); // 下采样系数
    SET_UVUP_EN(NUM_1); // 滤波开关
    SET_PORT_DU(NUM_22, NUM_11, NUM_11); // DU配置
    SET_PLANN_FMT(YUV_PLANNAR);
    return 0;
}

static int32_t yuv444p_format_info_init(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t format)
{
    switch (format) {
        case VPC_PIPE_PIXEL_FORMAT_YUV_PLANAR_444:
            SET_VPC_PIC_FMT(YUV444_PLANNAR, NV21);
            break;
        case VPC_PIPE_PIXEL_FORMAT_YVU_PLANAR_444:
            SET_VPC_PIC_FMT(YUV444_PLANNAR, NV12);
            break;
        default: return 1;
    }

    SET_PIXEL_FMT(D8, D8, D8);
    SET_PIXEL_STEP(NUM_1, NUM_1); // xstep/ystep
    SET_DOWN_SAMPLE_COEFF(NUM_13, NUM_65, NUM_100, NUM_65, NUM_13, NUM_0); // 下采样系数
    SET_UVUP_EN(NUM_1); // 滤波开关
    SET_PORT_DU(NUM_22, NUM_11, NUM_11); // DU配置
    SET_PLANN_FMT(YUV_PLANNAR);
    return 0;
}

static int32_t yuv440p_format_info_init(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t format)
{
    switch (format) {
        case VPC_PIPE_PIXEL_FORMAT_YUV_PLANAR_440:
            SET_VPC_PIC_FMT(YUV440_PLANNAR, NV21);
            break;
        case VPC_PIPE_PIXEL_FORMAT_YVU_PLANAR_440:
            SET_VPC_PIC_FMT(YUV440_PLANNAR, NV12);
            break;
        default: return 1;
    }

    SET_PIXEL_FMT(D8, D8, D8);
    SET_PIXEL_STEP(NUM_1, NUM_2); // xstep/ystep
    SET_DOWN_SAMPLE_COEFF(NUM_0, NUM_0, NUM_128, NUM_128, NUM_0, NUM_0); // 下采样系数
    SET_UVUP_EN(NUM_1); // 滤波开关
    SET_PORT_DU(NUM_22, NUM_11, NUM_11); // DU配置
    SET_PLANN_FMT(YUV_PLANNAR);
    return 0;
}

static int32_t yuv411p_format_info_init(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t format)
{
    switch (format) {
        case VPC_PIPE_PIXEL_FORMAT_YUV_PLANAR_411:
            SET_VPC_PIC_FMT(YUV411_PLANNAR, NV21);
            break;
        case VPC_PIPE_PIXEL_FORMAT_YVU_PLANAR_411:
            SET_VPC_PIC_FMT(YUV411_PLANNAR, NV12);
            break;
        default: return 1;
    }

    SET_PIXEL_FMT(D8, D8, D8);
    SET_PIXEL_STEP(NUM_4, NUM_1); // xstep/ystep
    SET_DOWN_SAMPLE_COEFF(NUM_0, NUM_0, NUM_128, NUM_128, NUM_0, NUM_0); // 下采样系数
    SET_UVUP_EN(NUM_0); // 滤波开关
    SET_PORT_DU(NUM_22, NUM_11, NUM_11); // DU配置
    SET_PLANN_FMT(YUV_PLANNAR);
    return 0;
}

/******************* yuv pkt*******************/
static int32_t yuv422pkt_format_info_init(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t format)
{
    switch (format) {
        case VPC_PIPE_PIXEL_FORMAT_YUYV_PACKED_422:
            SET_VPC_PIC_FMT(YUV422_PACKED, YUYV);
            break;
        case VPC_PIPE_PIXEL_FORMAT_UYVY_PACKED_422:
            SET_VPC_PIC_FMT(YUV422_PACKED, UYVY);
            break;
        case VPC_PIPE_PIXEL_FORMAT_YVYU_PACKED_422:
            SET_VPC_PIC_FMT(YUV422_PACKED, YVYU);
            break;
        case VPC_PIPE_PIXEL_FORMAT_VYUY_PACKED_422:
            SET_VPC_PIC_FMT(YUV422_PACKED, VYUY);
            break;
        default: return 1;
    }

    SET_PIXEL_FMT(YUV422PKT, IDEL, IDEL);
    SET_PIXEL_STEP(NUM_2, NUM_1); // xstep/ystep
    SET_DOWN_SAMPLE_COEFF(NUM_0, NUM_0, NUM_128, NUM_128, NUM_0, NUM_0); // 下采样系数
    SET_UVUP_EN(NUM_1); // 滤波开关
    SET_PORT_DU(NUM_22, NUM_11, NUM_11); // DU配置
    SET_PLANN_FMT(BUTT_PLANNAR);
    return 0;
}

static int32_t yuv444pkt_format_info_init(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t format)
{
    switch (format) {
        case VPC_PIPE_PIXEL_FORMAT_YUV_PACKED_444:
            SET_VPC_PIC_FMT(YUV444_PACKED, YUV);
            break;
        case VPC_PIPE_PIXEL_FORMAT_YVU_PACKED_444:
            SET_VPC_PIC_FMT(YUV444_PACKED, YVU);
            break;
        // 内部格式，多次pipeline的中间格式
        case VPC_PIPE_PIXEL_FORMAT_UVY_PACKED_444:
            SET_VPC_PIC_FMT(YUV444_PACKED, UVY);
            break;
        case VPC_PIPE_PIXEL_FORMAT_VUY_PACKED_444:
            SET_VPC_PIC_FMT(YUV444_PACKED, VUY);
            break;
        default: return 1;
    }

    SET_PIXEL_FMT(D24, IDEL, IDEL);
    SET_PIXEL_STEP(NUM_1, NUM_1); // xstep/ystep
    SET_DOWN_SAMPLE_COEFF(NUM_13, NUM_65, NUM_100, NUM_65, NUM_13, NUM_0); // 下采样系数
    SET_UVUP_EN(NUM_1); // 滤波开关
    SET_PORT_DU(NUM_22, NUM_11, NUM_11); // DU配置
    SET_PLANN_FMT(BUTT_PLANNAR);

    return 0;
}

int32_t vpc_pipe_init_yuv_field_format_info(vpc_fmt_info_t *fmt_info, vpc_pipe_pic_fmt_t fmt)
{
    CHECK_SUCC_RET(yuv420sp_format_info_init(fmt_info, fmt));
    CHECK_SUCC_RET(yuv422sp_format_info_init(fmt_info, fmt));
    CHECK_SUCC_RET(yuv444sp_format_info_init(fmt_info, fmt));
    CHECK_SUCC_RET(yuv440sp_format_info_init(fmt_info, fmt));
    CHECK_SUCC_RET(yuv411sp_format_info_init(fmt_info, fmt));

    CHECK_SUCC_RET(yuv420p_format_info_init(fmt_info, fmt));
    CHECK_SUCC_RET(yuv422p_format_info_init(fmt_info, fmt));
    CHECK_SUCC_RET(yuv444p_format_info_init(fmt_info, fmt));
    CHECK_SUCC_RET(yuv440p_format_info_init(fmt_info, fmt));
    CHECK_SUCC_RET(yuv411p_format_info_init(fmt_info, fmt));

    CHECK_SUCC_RET(yuv422pkt_format_info_init(fmt_info, fmt));
    CHECK_SUCC_RET(yuv444pkt_format_info_init(fmt_info, fmt));

    return 1;
}